//
//  RecorderManager.m
//  LinkUsMessage_iOS
//
//  Created by lcy on 15/12/31.
//  Copyright © 2015年 lcy. All rights reserved.
//

#import "LCYRecorderManager.h"
#import "lame.h"

#define TMP_CAF_FILE_PATH [NSString stringWithFormat:@"%@/tmp.caf", NSTemporaryDirectory()];

@interface LCYRecorderManager ()


@end

@implementation LCYRecorderManager


#pragma mark - 加载

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self initAudioSession];
    }
    
    return self;
}

- (void)initAudioSession
{
    NSError *error;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&error];
    if(error){
        NSLog(@"audioSession: %@ %d %@", [error domain], (int)[error code], [[error userInfo] description]);
        return;
    }
    
    error = nil;
    [audioSession setActive:YES error:&error];
    if(error){
        NSLog(@"audioSession: %@ %d %@", [error domain], (int)[error code], [[error userInfo] description]);
        return;
    }
    
    NSDictionary *recordSetting = @{
                                    AVSampleRateKey: [NSNumber numberWithFloat: 11025.0],                   //采样率
                                    AVFormatIDKey: [NSNumber numberWithInt:kAudioFormatLinearPCM],          //声音格式,采用MP3
                                    AVNumberOfChannelsKey:[NSNumber numberWithInt: 2],                      //通道数目
                                    AVEncoderAudioQualityKey:[NSNumber numberWithInt: AVAudioQualityLow]    //编码质量
                                    };
    
    NSString *filePath = TMP_CAF_FILE_PATH;  // 文件路径
    NSURL *recordedTmpFile = [NSURL fileURLWithPath:filePath];
    
    
    error = nil;
    _recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
    
    if (error) {
        NSLog(@"audioSession:%@", error);
        return;
    }
    
    BOOL audioHWAvailable = audioSession.inputAvailable;
    if (!audioHWAvailable) {
        NSLog(@"无法打开录音设备");
    }

}

// 初始化Player
- (void)initAudioPlayerWithUrl:(NSString *)urlStr
{
    NSError *error = nil;
    _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:urlStr] error:&error];
    
    if(error)
    {
        NSLog(@"init error  ---  %@", [error localizedDescription]);
    }
    
}

- (NSDate *)dateStartRecording
{
    if(_dateStartRecording == nil || self.isStop)
    {
        
        self.dateStartRecording = [NSDate date];
        
        self.recordTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(calculateDuration) userInfo:nil repeats:YES];
    }
    return _dateStartRecording;
}


- (NSDate *)dateStopRecording
{
    if(_dateStopRecording == nil || !self.isStop)
    {
        
        self.dateStopRecording = [NSDate date];
        
        [self.recordTimer invalidate];
    }
    return _dateStopRecording;
}

#pragma mark - 功能方法

- (void)startRecording
{
    NSLog(@"%@", self.dateStartRecording);
    
    [_recorder prepareToRecord];
    _recorder.meteringEnabled = YES;
    
    //录音
    [_recorder record];
    self.isStop = NO;
}

- (void)stopRecording
{
    NSLog(@"%@", self.dateStopRecording);
    
    //停止录音
    [_recorder stop];
    self.isStop = YES;
    
    [self audio_PCMtoMP3];
}

- (void)cancelRecording
{
    
}

// 返回录音时长
- (NSTimeInterval)recordedTimeInterval
{
    return (_dateStopRecording && _dateStartRecording) ? [_dateStopRecording timeIntervalSinceDate:_dateStartRecording] : 0;
}


#pragma mark - private method

- (NSString *)defaultFileName {
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *voiceDirectory = [documentsDirectory stringByAppendingPathComponent:@"voice"];
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:voiceDirectory]) {
        
        [[NSFileManager defaultManager] createDirectoryAtPath:voiceDirectory withIntermediateDirectories:YES attributes:nil error:NULL];
        
    }
    
    return [voiceDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%.0f.mp3", [_dateStartRecording timeIntervalSince1970]]];
    
}

// 超时确认
- (void)timeoutCheck:(id)sender {
    [[self delegate] recordingTimeout];
}


- (void)stopAnSaveRecordWithRemoteId:(NSString *)remoteId;
{
    if (_recorder.currentTime < 2) {
        [self stopRecording];
        NSLog(@"录音时间太短，请重新录音!");
        return;
    }
}


- (void)calculateDuration
{
    self.recordDurationTime = [[NSDate date] timeIntervalSinceDate:_dateStartRecording];
}

/**
 *  PCM音频格式转换成MP3格式
 */
- (void)audio_PCMtoMP3
{
    NSString *cafFilePath = TMP_CAF_FILE_PATH;
    
    @try {
        int read, write;
        
        FILE *pcm = fopen([cafFilePath cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header
        FILE *mp3 = fopen([[self defaultFileName] cStringUsingEncoding:1], "wb");  //output 输出生成的Mp3文件位置
        
        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        unsigned char mp3_buffer[MP3_SIZE];
        
        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 11025.0);
        lame_set_VBR(lame, vbr_default);
        lame_init_params(lame);
        
        do {
            read = fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
            if (read == 0)
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            else
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
            
            fwrite(mp3_buffer, write, 1, mp3);
            
        } while (read != 0);
        
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
    }
    @catch (NSException *exception) {
        NSLog(@"%@",[exception description]);
    }
    @finally {
        NSLog(@"MP3生成成功: %@",[self defaultFileName]);
    }
    
}

//播放
- (void)play
{
    [_audioPlayer play];
}
//暂停
- (void)pause
{
    [_audioPlayer pause];
}
//停止
- (void)stop
{
    _audioPlayer.currentTime = 0;  //当前播放时间设置为0
    [_audioPlayer stop];
}


@end
